package org.fioma.tree;

import java.io.BufferedWriter;
import java.io.IOException;

import org.fioma.general.Tools;

public class SimpleInternalNode<L extends Label<L>, I extends SimpleInternalNode<L, I, F, N>, F extends SimpleLeaf<L, I, F, N>, N extends Node<L, I, F, N>>
		extends SimpleNode<L, I, F, N> implements InternalNode<L, I, F, N> {

	private N[] nodes;
	protected TreeHandler<L, I, F, N> treeHandler;

	public SimpleInternalNode(I parent, L label, TreeHandler<L, I, F, N> treeHandler) {
		super(parent, label);
		this.treeHandler = treeHandler;
		nodes = createChildrenNodes();
	}

	// public AbstractInternalNode(I parent, L label, N[] nodes) {
	// super(parent, label);
	// this.nodes = nodes;
	// }
	//
	protected N getChild(byte letter) {
		return nodes[letter];
	}

	protected void setChild(byte letter, N node) {
		nodes[letter] = node;
	}

	public N[] createChildrenNodes() {
		return treeHandler.createChildrenNodes();
	}

	@Override
	public N[] getChilds() {
		return nodes;
	}

	@Override
	public N nextNode(char letter) {
		return nextNode(Tools.transformToByte(letter));
	}

	@Override
	public N nextNode(byte letter) {
		return getChild(letter);
	}

	@Override
	public void setChild(N node, char letter) {
		setChild(node, Tools.transformToByte(letter));
	}

	@Override
	public void setChild(N node, byte letter) {
		setChild(letter, node);
	}

	@Override
	public boolean isLeaf() {
		// for (Node<L, I, F> node : getChilds()) {
		// if (node != null) {
		// return false;
		// }
		// }
		return false;
	}

	@Override
	public I getOrCreateInternalNode(L word) {
		return treeHandler.getOrCreateInternalNode((I) this, word);
	}

	// // create new internal node in the position pos
	// protected I createChild(int pos, byte letter) {
	// return treeHandler.createChild((I) this, pos, letter);
	// }
	//
	@Override
	public I createChildInternalNode(L label) {
		return treeHandler.createChildInternalNode((I) this, label);
	}

	@Override
	public F createChildLeaf(L label) {
		return treeHandler.createChildLeaf((I) this, label);
	}

	@Override
	public F addWord(L word) {
		return treeHandler.addWord((I) this, word);
	}

	@Override
	public void printWords(BufferedWriter bw, String prefix) throws IOException {
		treeHandler.printWords((I) this, bw, prefix);
	}

	@Override
	public boolean find(L word) {
		return treeHandler.find((I) this, word);
	}

}
